//
//  KSShared.m
//  钰家家
//
//  Created by 孔 on 2023/5/31.
//

#import "KSShared.h"
#import <objc/runtime.h>
#import <MJExtension.h>
#import "KSFileUtil.h"

@implementation KSShared

+ (instancetype)shared{
    
    id instance = objc_getAssociatedObject(self, @"instance");
    if(!instance){
        instance = [[super allocWithZone:NULL] init];
        [instance _init];
        objc_setAssociatedObject(self, @"instance", instance, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return instance;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    return [self shared];
}

- (id)copyWithZone:(NSZone *)zone{
    return [self.class shared];
}

- (id)mutableCopyWithZone:(NSZone *)zone{
    return [self.class shared];
}

- (void)_init
{
    [self updateAllPropertys:[NSDictionary dictionaryWithContentsOfFile:cachePath(self.class)]];
}

- (instancetype)updateAllPropertys:(NSDictionary *)keyValues{
    return [self mj_setKeyValues:keyValues];
}

- (void)synchronize{
    [self.mj_keyValues writeToFile:cachePath(self.class) atomically:NO];
}

- (void)clear{
    
    unsigned int outCount = 0;
    objc_property_t* propertys = class_copyPropertyList(self.class, &outCount);
    for (int i = 0; i < outCount; i ++) {
        objc_property_t property = propertys[i];
        const char* property_name = property_getName(property);
        const char* types = property_getAttributes(property);
        if (types[1] == '@') {
            [self setValue:nil forKey:[NSString stringWithUTF8String:property_name]];
        }else{
            [self setValue:@(0) forKey:[NSString stringWithUTF8String:property_name]];
        }
    }
    free(propertys);
    
    NSFileManager* fileManager = [NSFileManager defaultManager];
    if([fileManager fileExistsAtPath:cachePath(self.class)]){
        [fileManager removeItemAtPath:cachePath(self.class) error:nil];
    }
}

NS_INLINE NSString* cachePath(Class cls){
    return [ks_documentPath() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.shared",NSStringFromClass(cls)]];
}

@end
